#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <unistd.h>
#include <signal.h>

void sig_pipe(int signo) {
	printf("SIGPIPE\n");
	exit(1);
}

int main() {	
	int n, fd1[2], fd2[2];
	pid_t pid;
	char line[4096];

	if (signal(SIGPIPE, sig_pipe) == SIG_ERR) {
		printf("signal error: %s\n", strerror(errno));
		return -1;
	}

	if (pipe(fd1)<0 || pipe(fd2)<0) {
		printf("pipe error: %s\n", strerror(errno));
		return -1;
	}

	if ((pid=fork()) < 0) {		
		printf("fork error: %s\n", strerror(errno));
		return -1;
	}
	else if (pid > 0) {
		close(fd1[0]);
		close(fd2[1]);

		while (fgets(line, 4096, stdin) != NULL) {
			n = strlen(line);
			if (write(fd1[1], line, n) != n) {
				printf("write error: %s\n", strerror(errno));
				return -1;
			}

			if ((n=read(fd2[0], line, 4096)) < 0) {
				printf("read error: %s\n", strerror(errno));
				return -1;
			}

			if (n == 0) {
				printf("child close pipe\n");
				break;
			}

			line[n] = '\0';
			if (fputs(line, stdout) == EOF) {				
				printf("fputs error: %s\n", strerror(errno));
				return -1;
			}
		}

		if (ferror(stdin)) {			
			printf("fgets error: %s\n", strerror(errno));
			return -1;
		}
	}
	else {
		close(fd1[1]);
		close(fd2[0]);

		if (fd1[0] != STDIN_FILENO) {
			if (dup2(fd1[0], STDIN_FILENO) != STDIN_FILENO) {			
				printf("dup2 error: %s\n", strerror(errno));
				return -1;
			}

			close(fd1[0]);
		}

		if (fd2[1] != STDIN_FILENO) {
			if (dup2(fd2[1], STDOUT_FILENO) != STDOUT_FILENO) {			
				printf("dup2 error: %s\n", strerror(errno));
				return -1;
			}

			close(fd2[1]);
		}

		if (execl("./15-10", "15-10", (char*)0) < 0) {		
			printf("execl error: %s\n", strerror(errno));
			return -1;
		}
	}

	return 0;
}